package sketch.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import randoop.RConstructor;
import randoop.RMethod;
import randoop.StatementKind;
import randoop.util.ConstructorReflectionCode;
import randoop.util.MethodReflectionCode;
import randoop.util.ReflectionCode;

public class ReflectiveExecutions {
	
	 public static ReflectionExecutionOutcome reflectiveExecute(Object receiver, StatementKind statement, Object...args) {
		if(statement instanceof RConstructor) {
			Constructor<?> constructor = ((RConstructor)statement).getConstructor();
			return executeConstructor(constructor, args);
		} else if (statement instanceof RMethod) {
			Method method = ((RMethod)statement).getMethod();
			return executeMethod(method, receiver, args);
		} else {
			throw new RuntimeException("The statement: " + statement.toParseableString()
					+ " is not in correct type.");
		}
	}
	
	//how about throwing an exception here?
	public static ReflectionExecutionOutcome executeConstructor(Constructor<?> constructor, Object...args) {
		Checker.checkNull(constructor, "The constructor could not be null!");
		Checker.checkNull(args, "The argument array could not be null!");
		ReflectionCode code = new ConstructorReflectionCode(constructor, args);
		try {
			code.runReflectionCode();
			return new ReflectionExecutionOutcome(code);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public static ReflectionExecutionOutcome executeMethod(Method method, Object receiver, Object...args) {
		Checker.checkNull(method, "The method could not be null!");
		Checker.checkNull(receiver, "The receiver object could not be null!");
		Checker.checkNull(args, "The argument array could not be null!");
		ReflectionCode code = new MethodReflectionCode(method, receiver, args);
		try {
			code.runReflectionCode();
			return new ReflectionExecutionOutcome(code);
		} catch (Exception e) {
			//throw new RuntimeException(e);
			//the code object include the exception obj
			return new ReflectionExecutionOutcome(code);
		}
	}
}
